package com.clstu.qqclient.service;

import com.clstu.qqclient.qqframe.JTextFieldSentMessage;
import com.clstu.qqclient.qqframe.OnlineListFrame;
import com.clstu.qqcommon.Message;
import com.clstu.qqcommon.MessageType;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.HashMap;

/**
 * 这是一个用于和服务端保持通信的线程类,主要用于接受消息并处理,不发送消息
 */
public class ClientConnectServerThread extends Thread{
    //该线程需要Socket对象,所以做成属性
    private final Socket socket;
    private final String userID;
    private HashMap<String,JTextFieldSentMessage> hm = new HashMap<>();//用于管理与各个用户的聊天框

    public HashMap<String, JTextFieldSentMessage> getHm() {
        return hm;
    }

    public ClientConnectServerThread(Socket socket, String uerID) {
        this.socket = socket;
        this.userID = uerID;
    }

    @Override
    public void run() {

        //因为需要在后台一直到和服务端保持通信,所以用while循环
        System.out.println("客户端线程,等待服务器端发送消息....");
        while (true){//一直读取消息

            try {
                ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
                //如果服务端没有发送消息,该线程就会一直阻塞在这里等着,类似于等待键盘输入..
                Message ms = (Message) ois.readObject();

                if(ms.getMesType().equals(MessageType.MESSAGE_RET_ONLINE_LIST)) {//如果是打印列表消息

                    //得到返回的用户列表并打印输出
                    String content = ms.getContent();
//                    String[] split = content.split(" ");
//                    System.out.println("\n====在线列表如下====");
//                    for (int i = 0; i < split.length; i++) {
//                        System.out.println("==用户" + (i + 1) + ": " + split[i]);
//                    }
                    new OnlineListFrame(userID,content);

                }else if(ms.getMesType().equals(MessageType.MESSAGE_COMMON_MES)||
                        ms.getMesType().equals(MessageType.MESSAGE_SENT_ALL)){//如果是私聊(或者群发)消息

                    //打印聊天内容
                    String sender = ms.getSender();
                    String s = ms.getContent();
                    JTextFieldSentMessage jTextFieldSentMessage = hm.get(ms.getSender());
                    if( jTextFieldSentMessage!= null){
                        jTextFieldSentMessage.sent(ms);
                    }else {
                        jTextFieldSentMessage = new JTextFieldSentMessage(userID);
                        jTextFieldSentMessage.getTxtGetter().setText(ms.getSender());
                        jTextFieldSentMessage.sent(ms);
                        hm.put(ms.getSender(),jTextFieldSentMessage);
                    }

                }else if(ms.getMesType().equals(MessageType.MESSAGE_SENT_FILE)){//如果是文件发送消息
                    String sender = ms.getSender();
                    String dest = ms.getDestPath();
                    String fileName = ms.getFileName();
                    JTextFieldSentMessage jTextFieldSentMessage = hm.get(ms.getSender());
                    if(jTextFieldSentMessage != null){
                        jTextFieldSentMessage.sent(sender+"发送文件: ["+fileName+"]\n");
                    }else {
                        jTextFieldSentMessage = new JTextFieldSentMessage(userID);
                        jTextFieldSentMessage.getTxtGetter().setText(ms.getSender());
                        jTextFieldSentMessage.sent(sender+"发送文件: ["+fileName+"]\n");
                        hm.put(ms.getSender(),jTextFieldSentMessage);
                    }

                    //保存文件
                    FileOutputStream fileOutputStream = new FileOutputStream(dest);//存到发送方指定的目标路径
                    fileOutputStream.write(ms.getData());
                    fileOutputStream.close();
                    jTextFieldSentMessage.sent("文件:"+fileName+"  已保存至目录["+dest+"]请注意查看...\n");
                }else {
                    //其他消息类型
                    System.out.println("其他消息类型,暂时不做处理...");
                }
            } catch (IOException | ClassNotFoundException e) {
                e.printStackTrace();
                try {
                    socket.close();
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
                System.out.println("\n客户端连接有异常,已退出连接....");
                break;//有异常就退出
            }

        }
    }

    //该方法给该对象持有的socket发送消息
    public void sentMessage(Message m){
        try {
            ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
            oos.writeObject(m);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public Socket getSocket() {
        return socket;
    }
}
